#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXN 110000
#define lson(x) ch[x][0]
#define rson(x) ch[x][1]

using namespace std;

typedef long long int LL;

struct edge
{
	int u,v,next;
}edges[MAXN*2];

int head[MAXN],nCount2=0;

void AddEdge(int U,int V)
{
	edges[++nCount2].u=U;
	edges[nCount2].v=V;
	edges[nCount2].next=head[U];
	head[U]=nCount2;
}

void add(int U,int V)
{
	AddEdge(U,V);
	AddEdge(V,U); //!!!!!!!
}

int dfn[MAXN],dfs_time=0;
int pos[MAXN]; //pos[i]=结点i在dfs序列dfn[]中的位置
int fa[MAXN][25];
int depth[MAXN];

void DFS(int u)
{
	dfn[++dfs_time]=u;
	pos[u]=dfs_time;
	for(int p=head[u];p!=-1;p=edges[p].next)
	{
		int v=edges[p].v;
		if(v==fa[u][0]) continue;
		fa[v][0]=u;
		depth[v]=depth[u]+1;
		DFS(v);
	}
}

int sum[MAXN*20],nCount=0; //区间和标记
int ch[MAXN*20][2]; //左右儿子

void Build(int old,int &now,int L,int R,int pos,int val) //在结点old的基础上，建立新的结点版本now,对应区间为[L,R],该版本对线段树的pos位置加上val
{
	now=++nCount;
	int M=(L+R)>>1;
	sum[now]=sum[old]+val;
	if(L==R) return;
	ch[now][0]=ch[old][0]; ch[now][1]=ch[old][1];
	if(pos<=M) Build(lson(old),lson(now),L,M,pos,val);
	else Build(rson(old),rson(now),M+1,R,pos,val);
}

int n,m;

void LCAprework()
{
	for(int j=1;j<25;j++)
		for(int i=1;i<=n;i++)
			fa[i][j]=fa[fa[i][j-1]][j-1];
}

int LCA(int a,int b)
{
	if(depth[a]<depth[b]) swap(a,b); //a比b深度大
	for(int i=24;i>=0;i--)
	{
		if(depth[fa[a][i]]<=depth[b]) continue;
		a=fa[a][i];
	}
	if(depth[a]>depth[b]) a=fa[a][0];
	if(a==b) return a;
	for(int i=24;i>=0;i--)
	{
		if(fa[a][i]==fa[b][i]) continue;
		a=fa[a][i],b=fa[b][i];
	}
	a=fa[a][0],b=fa[b][0];
	return a;
}

int stack[MAXN],top=0;
int root[MAXN];

int query(int x,int y,int K) //查询x到y路径上第K小权值
{
	int lca=LCA(x,y);
	int a=root[pos[x]],b=root[pos[y]],c=root[pos[lca]],d=root[pos[fa[lca][0]]];
	int L=1,R=top;
	while(L<R)
	{
		int M=(L+R)>>1;
		if(sum[lson(a)]+sum[lson(b)]-sum[lson(c)]-sum[lson(d)]>=K)
			a=lson(a),b=lson(b),c=lson(c),d=lson(d),R=M;
		else
			K-=sum[lson(a)]+sum[lson(b)]-sum[lson(c)]-sum[lson(d)],L=M+1,a=rson(a),b=rson(b),c=rson(c),d=rson(d); //!!!!!!!
	}
	return stack[L];
}

int val[MAXN];

int main()
{
	memset(head,-1,sizeof(head));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&val[i]),stack[++top]=val[i];
	for(int i=1;i<n;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
	}
	top=unique(stack+1,stack+top+1)-stack-1;
	sort(stack+1,stack+top+1);
	for(int i=1;i<=n;i++) val[i]=lower_bound(stack+1,stack+top+1,val[i])-stack;
	DFS(1);
	LCAprework(); //!!!!!
	for(int i=1;i<=n;i++)
		Build(root[pos[fa[dfn[i]][0]]],root[i],1,top,val[dfn[i]],1); //!!!!!!
	int lastans=0;
	while(m--)
	{
		int x,y,K;
		scanf("%d%d%d",&x,&y,&K);
		x^=lastans;
		lastans=query(x,y,K);
		printf("%d",lastans);
		if(m) printf("\n"); //此题文末换行符在BZOJ里会被判错
	}
	return 0;
}
